Bibliotecas Utlizadas

Primeiramente vamos importar as bibliotecas necessárias para esse script ser executado.

library(dplyr)
library(reshape2)
library(GGally)
library(ggplot2)
library(corrplot)
library(caret)

Carregando e Preparando os dados

Os dados estão em um arquivo em que cada linha representa uma relação entre uma aluno e uma disciplina.

Para facilitar as análises iremos obter dois data frames representando o primeiro e segundo período, de modo que esses data frames terão suas colunas organizadas da seguinte forma:

matricula, diciplina1, diciplina2, …, diciplinaN, cra

Carregando os dados

# Recebendo os dados, transformando a matricula em fator e ordenando por matricula
graduados = read.csv("~/graduados.csv") %>% mutate(matricula = factor(matricula)) %>% arrange(matricula)

# Retiramos as linhas que tem NA na media
graduados.clean <- graduados %>% 
  filter(!is.na(media))

Cálculo do CRA e organização do Data Frame

# Cálculo do CRA
graduados.cra <- graduados.clean %>%
  group_by(matricula) %>%
  mutate(cra.contrib = media*creditos) %>%
  summarise(cra = sum(cra.contrib)/sum(creditos))

# Selecionando apenas a nota final como media de um aluno em uma certa disciplina
# Renomando colunas da disciplina para um padrão mais fácil de se trabalhar
# Trocando linhas por colunas e adicionando coluna do CRA
graduados.model.input <- graduados.clean %>%
  group_by(matricula, disciplina) %>%
  filter(media == max(media))%>%
  ungroup() %>%
  select(matricula, disciplina, media) %>%
  mutate(disciplina = as.factor(gsub(" ", ".", disciplina))) %>%
  dcast(matricula ~ disciplina, mean) %>%
  merge(graduados.cra)
## Using media as value column: use value.var to override.

Selecionando dados referentes ao primeiro e segundo período

# Selecionado apenas disciplinas do primeiro período
primeiro.periodo <- graduados.model.input %>% select(matricula, cra, Cálculo.Diferencial.e.Integral.I, Álgebra.Vetorial.e.Geometria.Analítica, Leitura.e.Produção.de.Textos, Programação.I, Introdução.à.Computação, Laboratório.de.Programação.I)

primeiro.periodo <- na.omit(primeiro.periodo)
colnames(primeiro.periodo) <- c("matricula", "cra", "Cálculo1", "Vetorial", "LPT", "P1", "IC", "LP1")

head(primeiro.periodo)
##   matricula      cra Cálculo1 Vetorial LPT  P1  IC LP1
## 1 103343436 8.357317      7.5      9.5 8.8 9.0 8.9 8.4
## 2 104343425 8.113253      7.7      7.8 8.3 8.0 9.5 8.8
## 5 104343429 7.722892      7.0      7.8 8.8 7.0 9.1 6.1
## 7 104343431 7.875294      7.1      7.6 8.5 6.6 9.3 9.1
## 8 104343438 7.118391      5.4      7.0 9.0 7.0 8.6 7.6
## 9 105343538 7.571765      6.1      5.4 9.2 7.0 8.5 7.9
# Selecionado apenas disciplinas do segundo período
segundo.periodo <- graduados.model.input %>%
  select(matricula, cra, Cálculo.Diferencial.e.Integral.II, Matemática.Discreta, Programação.II, Teoria.dos.Grafos, Fundamentos.de.Física.Clássica, Laboratório.de.Programação.II)

segundo.periodo <- na.omit(segundo.periodo)
colnames(segundo.periodo) <- c("matricula", "cra", "Cálculo2", "Discreta", "P2", "Grafos", "Fís.Clássica", "LP2")

head(segundo.periodo)
##     matricula      cra Cálculo2 Discreta  P2 Grafos Fís.Clássica LP2
## 24 1268289547 6.760440      5.3      5.0 8.4    7.8          5.5 7.9
## 26 1269495444 7.200000      6.3      6.4 7.1    7.1          7.3 5.1
## 27 1269495448 7.796471      5.7      7.9 7.9    7.0          8.7 8.0
## 29 1270495442 8.802353      8.3      8.1 8.9    7.6          9.1 9.1
## 30 1270495450 6.812500      5.0      5.9 7.3    5.6          5.0 7.1
## 31 1272495432 7.205747      5.0      5.8 7.1    5.4          8.7 8.2
# DataFrame dos dois períodos
primeiro.segundo.periodo <- merge(primeiro.periodo, segundo.periodo)
head(primeiro.segundo.periodo)
##    matricula      cra Cálculo1 Vetorial LPT  P1  IC LP1 Cálculo2 Discreta
## 1 1268289547 6.760440      7.7      6.2 8.0 8.1 7.1 8.5      5.3      5.0
## 2 1269495444 7.200000      8.6      8.0 8.8 5.5 7.2 7.2      6.3      6.4
## 3 1269495448 7.796471      5.9      8.1 8.0 6.2 8.4 6.7      5.7      7.9
## 4 1270495442 8.802353      8.7      9.1 8.2 8.1 9.9 8.6      8.3      8.1
## 5 1272495432 7.205747      5.2      8.8 9.3 5.0 8.5 5.1      5.0      5.8
## 6 1272495434 8.924706      9.5      9.2 8.0 8.9 9.8 9.8      8.1      8.0
##    P2 Grafos Fís.Clássica LP2
## 1 8.4    7.8          5.5 7.9
## 2 7.1    7.1          7.3 5.1
## 3 7.9    7.0          8.7 8.0
## 4 8.9    7.6          9.1 9.1
## 5 7.1    5.4          8.7 8.2
## 6 9.3    9.8          8.2 9.1

Pergunta Principal

“O desempenho dos alunos nos dois primeiros períodos consegue explicar, em algum grau, seus desempenhos no curso como um todo?”

Passos para responder a pergunta:

  1. Um modelo de regressão múltipla com todas as variáveis é plausível para explicar a variação em y? Em que grau?

  2. Todas as variáveis são úteis para o modelo de regressão?

  3. Se a resposta para a pergunta anterior foi não, construa um novo modelo sem essas variáveis e o compare ao modelo com todas as variáveis (e.g. em termos de R2 e RSE).

  4. Analise os plots de resíduos de cada variável e veja se algum (um ou mais) deles indica não aleatoriedade dos erros.

  5. Que período consegue explicar melhor o desempenho final (primeiro ou segundo)?

  6. Use o modelo para predizer o seu próprio desempenho e compare a predição com o seu CRA atual. Comente o resultado.

Sessão 1 - Modelos de Regressão

Esta sessão busca responder as seguintes perguntas:

1. Um modelo de regressão múltipla com todas as variáveis é plausível para explicar a variação em y? Em que grau?

4. Analise os plots de resíduos de cada variável e veja se algum (um ou mais) deles indica não aleatoriedade dos erros.

5. Que período consegue explicar melhor o desempenho final (primeiro ou segundo)?

Para tal, foi feita uma análise de 3 regressões lineares múltiplas: uma utilizando dados do primeiro e segundo período, outra utilizando apenas dados do primeiro período e outra utilizando apenas dados do segundo período. Perceba que nesta sessão nenhuma variável foi tratada ou retirada, isso foi feito pois o objetivo é justamente analisar o período como um todo, na próxima sessão buscaremos analisar as variáveis e melhorar os modelos se possível.

Após realizar as regressões os resultados foram discutidos. Para cada regressão foram plotados os seguintes gráficos:

  • termplot

    Este gráfico plota os termos da regressão e seus preditores, opcionalmente temos também o erro padrão e resíduos parciais. A linha tracejada nesse gráfico pode nos dar algumas dicas para um melhor modelo para uma certa variável, por exemplo: se a linha tracejada tiver a forma de uma parábola, talvez um modelo polinomial quadrático se adeque melhor à variável.

  • Residual Vs Fitted

    O objetivo de utilizar esse gráfico é verificar a não existência de padrão na distribuição dos erros, já que esses erros devem ser aleatórios.

  • Normal Q-Q

    Esse gráfico é útil para verificarmos se os resíduos apresentam uma distribuição normal.

  • predição vs observação

    Esse gráfico apresenta as observações reais em um eixo e os valores encontrados pelo modelo no outro eixo, assim o ideal é que a distribuição dessas observações esteja concentrada em regiões próximas à reta da função identidade y = f(x) = x.

Regressão P1

Regressão utilizando apenas notas do primeiro período. Esse data frame tem 291 observações e para a regressão foram utilizadas 6 variáveis representando as notas em disciplinas do primeiro período:

  • Cálculo Diferencial e Integral I
  • Álgebra Vetorial e Geometria Analítica
  • Leitura e Produção de Textos
  • Programação I
  • Introdução à Computação
  • Laboratório de Programação I

O y é o CRA do aluno ao final do curso.

lm.p1 <- lm(cra ~ ., data = primeiro.periodo %>% select(- matricula))
summary(lm.p1)
## 
## Call:
## lm(formula = cra ~ ., data = primeiro.periodo %>% select(-matricula))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.53290 -0.31108  0.07564  0.37949  1.31148 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.89445    0.38666   2.313 0.021423 *  
## Cálculo1     0.11604    0.02803   4.141 4.57e-05 ***
## Vetorial     0.12305    0.03221   3.821 0.000164 ***
## LPT          0.11915    0.03672   3.245 0.001315 ** 
## P1           0.06425    0.04076   1.576 0.116054    
## IC           0.32061    0.04853   6.606 1.94e-10 ***
## LP1          0.08620    0.04219   2.043 0.041974 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5668 on 284 degrees of freedom
## Multiple R-squared:  0.5488, Adjusted R-squared:  0.5392 
## F-statistic: 57.56 on 6 and 284 DF,  p-value: < 2.2e-16

Assim, podemos observar que a regressão linear apresenta um p-valor bastante baixo: 2.2e^-16, e um R² ajustado consideravalmente alto: 0.5392, de modo que o modelo se mostra válido!

O p-valor nos diz qual a probabilidade de o modelo linear ter se ajustado bem aos dados por acaso, um p-valor baixo significa que há uma baixa probabilidade do “acaso” ter ocorrido e portanto nosso modelo representa bem os dados.

Já o R² nos diz o quanto o modelo consegue explicar os valores observados e este valor varia entre [0, 1] quanto mais próximo de 1 melhor. No caso da regressão acima o modelo consegue explicar ~54% dos resultados de CRA final.

Já em relação as variáveis: a maioria apresenta um p-valor baixíssimo, destaco: IC, Cálculo 1 e Vetorial como as que têm os menores p-valor. A única variável que apresenta um p-valor considerado alto é P1 de modo que provavelmente sua relação com o CRA não é linear ou sua relação com o CRA pode estar sendo explicada por outra variável, talvez LP1, discutiremos essa possibilidade na próxima sessão.

Cada variável e sua relação com a variável CRA podem ser melhor vistas no gráfico abaixo.

# Gráficos de regressão de cada variável
par(mfrow=c(1,6))
termplot(lm.p1, partial.resid = TRUE, smooth = panel.smooth, span.smth = 1/4)

Com os gráficos abaixo percebemos que em geral o erro segue uma distribuição normal com alguns dados que não seguem a distribuição na parte inferior e superior do plot. E não há nenhum padrão aparente no plot de predições Vs resíduos.

# Gráficos informativos
par(mfrow=c(2,1))                   
plot(lm.p1, which = 1:2)

Regressão P2

Regressão utilizando apenas notas do segundo período. O data frame utilizado tem 112 observações e para a regressão foram utilizadas 6 variáveis representando as notas nas disciplinas do segundo período:

  • Cálculo Diferencial e Integral II
  • Matemática Discreta
  • Programação II
  • Teoria dos Grafos
  • Fundamentos de Física Clássica
  • Laboratório de Programação II

O y é o CRA do aluno ao final do curso.

lm.p2 <- lm(cra ~ ., data = segundo.periodo %>% select(- matricula))
summary(lm.p2)
## 
## Call:
## lm(formula = cra ~ ., data = segundo.periodo %>% select(-matricula))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.59303 -0.35328  0.08232  0.34269  1.01093 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.101453   0.488158   4.305 3.76e-05 ***
## Cálculo2     0.018291   0.048695   0.376  0.70795    
## Discreta     0.266726   0.054252   4.916 3.27e-06 ***
## P2           0.257116   0.086630   2.968  0.00371 ** 
## Grafos       0.129179   0.052604   2.456  0.01570 *  
## Fís.Clássica 0.039475   0.053422   0.739  0.46160    
## LP2          0.004893   0.056411   0.087  0.93105    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5048 on 105 degrees of freedom
## Multiple R-squared:  0.6628, Adjusted R-squared:  0.6435 
## F-statistic:  34.4 on 6 and 105 DF,  p-value: < 2.2e-16

Assim, podemos observar que a regressão linear apresenta um p-valor bastante baixo: 2.2e^-16, e um R² ajustado consideravalmente alto: 0.6435, de modo que o modelo se mostra válido!

Já em relação às variáveis apenas uma disciplinas apresenta p-valor muito baixo que é Discreta, P2 e Grafos também apresentam um p-valor baixo, assim provavelmente tem uma relação muito forte com o CRA final do aluno. Outras têm um p-valor considerado alto, como: LP2, Física Clássica e Cálculo 2 de modo que provavelmente a relação que apresentam com o CRA não é linear ou já está sendo explicada por outra variável.

Devido ao grande número de variáveis com alto p-valor, é provável que alguma variável de baixo p-valor esteja basicamente “explicando os dados sozinhas”, analisaremos essa possibilidade mais a fundo na próxima sessão.

Cada variável e sua relação com a variável CRA podem ser melhor vistas no gráfico abaixo.

# Gráficos de regressão de cada variável
par(mfrow=c(1,6))
termplot(lm.p2, partial.resid = TRUE, smooth = panel.smooth, span.smth = 1/4)

Já com os gráficos abaixo percebemos que em geral o erro segue uma distribuição normal e tem bem menos “outliers” que a regressão utilizando o P1, isso é esperado já que o R² foi consideravelmente superior, vale a pena ainda analisar o RMSE (isso foi feito na conclusão desta sessão). E não há nenhum padrão aparente no plot de previsões Vs resíduos.

# Gráficos informativos
par(mfrow=c(2,1))                   
plot(lm.p2, which=1:2)

Regressão P1 e P2

Regressão utilizando notas do primeiro e segundo períodos. O data frame utilizado tem 103 observações e para a regressão foram utilizadas 12 variáveis representando as notas nas disciplinas do primeiro e segundo período.

lm.p1.p2 <- lm(cra ~ ., data = primeiro.segundo.periodo %>% select(- matricula))
summary(lm.p1.p2)
## 
## Call:
## lm(formula = cra ~ ., data = primeiro.segundo.periodo %>% select(-matricula))
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.8273 -0.2988  0.1069  0.2796  1.0032 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.33894    0.59783   2.240  0.02758 *  
## Cálculo1      0.02121    0.04907   0.432  0.66661    
## Vetorial      0.04443    0.04762   0.933  0.35327    
## LPT           0.09172    0.05167   1.775  0.07925 .  
## P1           -0.02593    0.07684  -0.337  0.73660    
## IC            0.10196    0.08639   1.180  0.24098    
## LP1          -0.02472    0.07450  -0.332  0.74082    
## Cálculo2     -0.00100    0.05302  -0.019  0.98499    
## Discreta      0.23935    0.05863   4.083 9.63e-05 ***
## P2            0.29214    0.09553   3.058  0.00293 ** 
## Grafos        0.09620    0.06302   1.526  0.13040    
## Fís.Clássica -0.01024    0.06120  -0.167  0.86745    
## LP2          -0.02848    0.06666  -0.427  0.67024    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5046 on 90 degrees of freedom
## Multiple R-squared:  0.6889, Adjusted R-squared:  0.6474 
## F-statistic: 16.61 on 12 and 90 DF,  p-value: < 2.2e-16

Assim, podemos observar que a regressão linear apresenta um p-valor bastante baixo: 2.2e^-16, e um R² ajustado consideravalmente alto: 0.647, de modo que o modelo se mostra válido!

Já em relação às variáveis apenas uma disciplinas apresenta p-valor muito baixo que é Discreta, P2 e LPT também apresentam um p-valor baixo. As demais variáveis apresentam um p-valor considerado alto.

É notável que essa regressão foi a que apresentou até agora maior R², mas isso já é esperado já que utilizamos mais variáveis para fazer a regressão, claro nem sempre aumentar o número de variáveis representará uma melhora no modelo, neste caso a melhora em relação à regressão utilizando apenas disciplinas do segundo período foi basicamente insignificante, apesar de termos dobrarmos o número de variáveis utilizadas no modelo.

Cada variável e sua relação com a variável CRA podem ser melhor vistas no gráfico abaixo.

# Gráficos de regressão de cada variável
par(mfrow=c(2,6))
termplot(lm.p1.p2, partial.resid = TRUE, smooth = panel.smooth, span.smth = 1/4)

Já com os gráficos abaixo percebemos que em geral o erro segue uma distribuição normal e tem bem menos “outliers” que a regressão utilizando o P1, porém mais outliers que a regressão utilizando apenas P2. E não há nenhum padrão aparente no plot de previsões Vs resíduos.

# Gráficos informativos
par(mfrow=c(2,1))                   
plot(lm.p1.p2, which = 1:2)

Conclusão

A regressão com maior R², ou seja que cujo modelo mais “explicou” os dados, foi a que utilizou as disciplinas de ambos os períodos, resultado esse nada surpreendente, pois utilizamos o dobro de variáveis que nas outras regressões.

É interessante perceber também a mudança dos “p-valores” ao utilizar diferentes regressões, uma pergunta interessante é: por que a regressão que utiliza apenas disciplinas do segundo periódo tem os maiores p-valores (por variável) e ainda sim apresenta um R² bastante superior aos da regressão que utiliza disciplinas do primeiro período? Uma hipótese é devido à maior “influência” das variáveis de p-valor pequeno do segundo modelo (no caso Discreta) para o CRA.

Além disso, perceba que a regressão que utiliza apenas o P1 têm consideravalmente mais dados do que as demais e talvez esses dados dificultem o ajuste do modelo linear no conjunto como um todo (sejam outliers).

Vale também destacar o quão concentrados estão os erros da regressão que utiliza apenas P1 na reta da normal, apesar dos “outliers” a grande maioria das observações estão concentradas na reta.

Por fim vamos comparar as regressões utilizando o R² e o RMSE.

Comparando as regressões

resultado.p1 <- data.frame(pred = predict(lm.p1, primeiro.periodo %>% select(-matricula) %>% select(-cra)), obs = primeiro.periodo$cra)

resultado.p2 <- data.frame(pred = predict(lm.p2, segundo.periodo %>% select(-matricula) %>% select(-cra)), obs = segundo.periodo$cra)

resultado.p1.p2 <- data.frame(pred = predict(lm.p1.p2, primeiro.segundo.periodo %>% select(-matricula) %>% select(-cra)), obs = primeiro.segundo.periodo$cra)

resultado.p1$modelo <- "P1"
resultado.p2$modelo <- "P2"
resultado.p1.p2$modelo <- "P1 + P2"

comparacao <- rbind(resultado.p1, resultado.p2, resultado.p1.p2)

ggplot(comparacao, aes(x = pred, y = obs)) + 
  geom_point(alpha = 0.5, position = position_jitter(width=0.2)) + 
  facet_grid(. ~ modelo) + 
  geom_abline(color="red") 

round(defaultSummary(resultado.p1), digits = 3)
##     RMSE Rsquared 
##    0.560    0.549
round(defaultSummary(resultado.p2), digits = 3)
##     RMSE Rsquared 
##    0.489    0.663
round(defaultSummary(resultado.p1.p2), digits = 3)
##     RMSE Rsquared 
##    0.472    0.689

Portanto, de fato a regressão que utiliza apenas o segundo período aparentemente se saiu melhor que a do P1, apresentando um RMSE menor e um R² maior. E ainda tendo um resultado similar à regressão que utiliza todas as disciplinas (P1 + P2)

Sessão 2 - Análise das variáveis

Todas as variáveis são úteis para o modelo de regressão? Se a resposta para a pergunta anterior foi não, construa um novo modelo sem essas variáveis e o compare ao modelo com todas as variáveis (e.g. em termos de R2 e RSE).

Analisando histograma

Verificaremos primeiro como estão distríbuidas as notas em cada disciplina, o ideal é que as variáveis apresentem uma distribuição aproximadamente normal.

# Histograma das disciplinas
ggplot(melt(primeiro.segundo.periodo),aes(x = value)) + 
    facet_wrap(~variable, scales = "free_x") + 
    geom_histogram(aes(fill=..count..))
## Using matricula as id variables
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

A partir do histograma acima podemos perceber que algumas variáveis (como P2, Física Clássica, LP2) poderiam ser normalizadas para obter um melhor modelo mais representativo, isso não será feito pois não é o foco deste laboratório.

Analisando a correlação entre variáveis

Para verificar quais variáveis realmente são úteis para os modelos iremos analisar a correlação entre as variáveis buscando altas correlações. Se duas variáveis apresentam alta correlação talvez uma dessas variáveis possa ser retirada, porque de certo modo a outra variável “explicará” sua influência no modelo.

# Correlação entre as disciplinas
ggcorr(primeiro.segundo.periodo %>% select(-matricula), palette = "RdBu", label = TRUE, label_round = 3)

# Análise completa da relação entre as disciplinas
ggpairs(primeiro.segundo.periodo %>% select(-matricula))

Observando a correlação vemos que a maioria das variáveis tem uma correlação entre [0.4, 0.55], portanto utilizar um threshold de 0.6 para identificar altas correlações é viável, assim:

  • P1 e LP1 tem uma alta correlação e portanto utilizar só uma destas variáveis faz sentido, utilizaremos apenas LP1, pois P1 apresenta outras correlações altas com outras variáveis.

  • Podemos retirar do nosso modelo P2, pois possui uma alta correlação com Discreta e Grafos.

  • IC também apresenta alta correlação com Discreta e uma correlação próxima a ser considerada alta com outras disciplinas e por isso será retirada.

Testando novos modelos

Portanto, retirando as variáveis com alta correlação, obtivemos um modelo com as seguintes variáveis:

  • Cálculo 1
  • Vetorial
  • LPT
  • LP1
  • Discreta
  • Grafos
  • Cálculo 2
  • Física Clássica
  • LP2

Vamos ver como esse modelo se sai, analisaremos os modelos daqui para frente a partir do R² quadrado que mede o quanto dos dados explicamos com nosso modelo:

df.tentativa1 <- graduados.model.input %>% select(Cálculo.Diferencial.e.Integral.I, Álgebra.Vetorial.e.Geometria.Analítica, Leitura.e.Produção.de.Textos, Laboratório.de.Programação.I, Matemática.Discreta, Teoria.dos.Grafos, Cálculo.Diferencial.e.Integral.II, Fundamentos.de.Física.Clássica, Laboratório.de.Programação.II, matricula, cra) %>%
  na.omit()

colnames(df.tentativa1) <- c("Calculo1", "Vetorial", "LPT", "LP1", "Discreta", "Grafos", "Calculo2", "Fis.Classica", "LP2", "matricula", "cra")
  
lm.tentativa1 <- lm(cra ~ ., data = df.tentativa1 %>% select(- matricula))
summary(lm.tentativa1)
## 
## Call:
## lm(formula = cra ~ ., data = df.tentativa1 %>% select(-matricula))
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.9587 -0.3040  0.0876  0.3211  0.9639 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.79568    0.59491   3.018  0.00328 ** 
## Calculo1      0.03678    0.05054   0.728  0.46865    
## Vetorial      0.07263    0.04777   1.520  0.13181    
## LPT           0.07445    0.05268   1.413  0.16089    
## LP1           0.02614    0.05470   0.478  0.63391    
## Discreta      0.28986    0.05858   4.948 3.33e-06 ***
## Grafos        0.16912    0.05589   3.026  0.00320 ** 
## Calculo2      0.01396    0.05479   0.255  0.79939    
## Fis.Classica  0.02906    0.05914   0.491  0.62433    
## LP2           0.05550    0.06144   0.903  0.36863    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.525 on 93 degrees of freedom
## Multiple R-squared:  0.652,  Adjusted R-squared:  0.6183 
## F-statistic: 19.36 on 9 and 93 DF,  p-value: < 2.2e-16

O modelo testado apresenta um R² quadrado ajustado de ~ 0.62 que podemos tentar melhorar.

Após alguns testes manuais com algumas variáveis pude perceber que P2 apesar da alta correlação com outras variáveis se mostra fundamental para um maior R² no modelo, então vamos substituir LP2 por P2 no modelo anterior.

df.tentativa2 <- graduados.model.input %>% select(Cálculo.Diferencial.e.Integral.I, Álgebra.Vetorial.e.Geometria.Analítica, Leitura.e.Produção.de.Textos, Laboratório.de.Programação.I, Matemática.Discreta, Teoria.dos.Grafos, Cálculo.Diferencial.e.Integral.II, Fundamentos.de.Física.Clássica, Programação.II, matricula, cra) %>%
  na.omit()

colnames(df.tentativa2) <- c("Calculo1", "Vetorial", "LPT", "LP1", "Discreta", "Grafos", "Calculo2", "Fis.Classica", "P2", "matricula", "cra")
  
lm.tentativa2 <- lm(cra ~ ., data = df.tentativa2 %>% select(- matricula))
summary(lm.tentativa2)
## 
## Call:
## lm(formula = cra ~ ., data = df.tentativa2 %>% select(-matricula))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.77954 -0.30274  0.07678  0.29610  0.95450 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.476412   0.561155   2.631  0.00996 ** 
## Calculo1      0.031625   0.047307   0.668  0.50548    
## Vetorial      0.057583   0.045758   1.258  0.21138    
## LPT           0.082184   0.046050   1.785  0.07758 .  
## LP1          -0.031081   0.055199  -0.563  0.57475    
## Discreta      0.251045   0.057142   4.393 2.96e-05 ***
## Grafos        0.105062   0.055690   1.887  0.06234 .  
## Calculo2      0.001417   0.051313   0.028  0.97804    
## Fis.Classica  0.014410   0.056543   0.255  0.79941    
## P2            0.278259   0.087236   3.190  0.00194 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5007 on 93 degrees of freedom
## Multiple R-squared:  0.6835, Adjusted R-squared:  0.6529 
## F-statistic: 22.32 on 9 and 93 DF,  p-value: < 2.2e-16

De fato o R² ajustado subiu consideravelmente sendo o maior encontrado até agora. Vamos tentar remover algumas variáveis para verificar se aumentamos ainda mais o R², removeremos Cálculo 2 e Física Clássica que apresentam o maior p-valor no modelo acima.

df.tentativa3 <- df.tentativa2 %>% select(-Calculo2) %>%select(-Fis.Classica) %>% na.omit()

lm.tentativa3 <- lm(cra ~ ., data = df.tentativa3 %>% select(- matricula))
summary(lm.tentativa3) 
## 
## Call:
## lm(formula = cra ~ ., data = df.tentativa3 %>% select(-matricula))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.78056 -0.31375  0.07086  0.29535  0.95526 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.52645    0.52266   2.921  0.00436 ** 
## Calculo1     0.03149    0.04564   0.690  0.49193    
## Vetorial     0.05988    0.04446   1.347  0.18130    
## LPT          0.08270    0.04511   1.833  0.06992 .  
## LP1         -0.03282    0.05407  -0.607  0.54530    
## Discreta     0.25656    0.05232   4.904 3.88e-06 ***
## Grafos       0.10383    0.05342   1.944  0.05488 .  
## P2           0.28154    0.08467   3.325  0.00126 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4955 on 95 degrees of freedom
## Multiple R-squared:  0.6833, Adjusted R-squared:   0.66 
## F-statistic: 29.28 on 7 and 95 DF,  p-value: < 2.2e-16

De fato o R² subiu consideravelmente, a esse ponto mais modelos foram testados e aqui não foram apresentados pois nenhuma melhora significativa foi conseguida. Assim iremos detalhar melhor esse terceiro modelo.

Melhor modelo linear obtido

Para esse modelo foram utilizadas 103 observações, e as seguintes variáveis para modelar o CRA:

  • Cálculo 1
  • Vetorial
  • LPT
  • LP1
  • Discreta
  • Grafos
  • P2

Assim foi obtido um R² ajustado de 0.66. Mais detalhes sobre esse modelo podem ser vistos nos gráficos abaixo:

resultado.tentativa3 <- data.frame(pred = predict(lm.tentativa3, df.tentativa3 %>% select(-matricula) %>% select(-cra)), obs = df.tentativa3$cra)

resultado.tentativa3$modelo <- "Tentativa 3"

ggplot(resultado.tentativa3, aes(x = pred, y = obs)) + 
  geom_point(alpha = 0.5, position = position_jitter(width=0.2)) + 
  facet_grid(. ~ modelo) + 
  geom_abline(color="red") 

round(defaultSummary(resultado.tentativa3), digits = 3)
##     RMSE Rsquared 
##    0.476    0.683

Perceba que apesar de um R² ajustado maior que o modelo P1.P2, esse novo modelo apresenta maior RMSE (o modelo P1.P2 apresentou RMSE de 0.472).

# Gráficos informativos
par(mfrow=c(2,1))                   
plot(lm.tentativa3, which = 1:2)

Assim como os demais modelos: não há padrão nos erros e os resíduos apresentam uma distribuição relativamente normal.

Sessão 3 - Predizendo o CRA

Para tal criaremos um data frame contendo as minhas notas das disciplinas do primeiro e segundo período, além de um data frame contendo apenas as notas utilizadas no modelo “ótimo” encontrado na sessão anterior.

#1109035    ALGEBRA VETORIAL E GEOMETRIA ANALÍTICA  Obrigatória 4   60  10,0    Aprovado    2014.1
#1109103    CALCULO DIFERENCIAL E INTEGRAL I    Obrigatória 4   60  8,3 Aprovado    2014.1
#1411174    INTRODUÇÃO A COMPUTAÇÃO Obrigatória 4   60  9,9 Aprovado    2014.1
#1411180    LABORATÓRIO DE PROGRAMAÇÃO I    Obrigatória 4   60  10,0    Aprovado    2014.1
#1307151    LEITURA E PRODUCAO DE TEXTOS    Obrigatória 4   60  9,2 Aprovado    2014.1
#1411167    PROGRAMAÇÃO I   Obrigatória 4   60  10,0    Aprovado    2014.1
#1109053    CALCULO DIFERENCIAL E INTEGRAL II   Obrigatória 4   60  9,8 Aprovado    2014.2
#1108089    FUNDAMENTOS DE FÍSICA CLÁSSICA  Obrigatória 4   60  9,7 Aprovado    2014.2
#1411181    LABORATÓRIO DE PROGRAMAÇÃO II   Obrigatória 4   60  9,7 Aprovado    2014.2
#1109113    MATEMÁTICA DISCRETA Obrigatória 4   60  10,0    Aprovado    2014.2
#1411168    PROGRAMAÇÃO II  Obrigatória 4   60  9,8 Aprovado    2014.2
#1411170    TEORIA DOS GRAFOS   Obrigatória 2   30  10,0    Aprovado    2014.2

notas.p1.p2 = data.frame(Cálculo1 = 8.3, Vetorial = 10, LPT = 9.2, P1 = 10, IC=9.9, LP1 =10, Cálculo2 = 9.8, Discreta = 10, P2 = 9.8, Grafos = 10, Fís.Clássica = 9.7, LP2 = 9.7)

notas.tentativa3 = data.frame(Calculo1 = 8.3, Vetorial = 10, LPT = 9.2, LP1 = 10, Discreta = 10, Grafos = 10, P2 = 9.8)

predict(lm.p1.p2, notas.p1.p2)
##        1 
## 9.139253
predict(lm.tentativa3, notas.tentativa3)
##       1 
## 9.18222

Ambos os modelos previram um CRA de ~9.1, o que chegou mais perto foi o modelo a partir das tentativas, mas este modelo não se saiu muito melhor que o modelo que utiliza todas as disciplinas do P1 e P2. Meu CRA atual é de 9.69, de modo que a partir das notas do primeiro e segundo período utilizando um modelo linear o valor da predição apresentou um resultado razoável.

Sabemos que os modelos apresentam resultados representativos, mas não são tão precisos. Isso pode se dar pelo fato de termos utilizado apenas um modelo linear, um número maior de observações também poderia auxiliar o modelo, ou talvez a falta de variáveis explicativas no modelo.